#ifndef ALGORITHM_H
#define ALGORITHM_H

#include <string>

#include <profo/profo.h>
#include <profo/Protein.h>

namespace profo {

/**
 * An abstract IAlgorithm class provides the interface for all future implementations
 * of protein folding algorithms.
 */
class IAlgorithm {
  public:
  // VARIABLES
  // We can safely set this as default values...
  std::string desc; ///< Algorithm description
  std::string auth; ///< List of authors
  // METHODS
  IAlgorithm(Protein& arg): _proteinRef(arg) {}

  virtual GridType gridType() = 0; ///< gridType() method must be implemented by subclasses
  virtual bool is3D() = 0; ///< is3D() should return true if algorithm is in 3D space.
  virtual bool isRectangular() = 0;
  virtual void setProtein(Protein& arg) = 0;
  virtual double energy() const = 0;
  virtual double energy(const Protein& arg) const = 0;
  ///< This method gives yet another way to specify input protein sequence.
  virtual void initProtein(const char* arg) = 0;
  virtual void updateFreeMoves() = 0;
  virtual unsigned char getAvailableMoves(unsigned int arg) = 0;
  virtual void move(unsigned char arg) = 0;
  virtual bool checkValidity(unsigned int arg = 0) const = 0;

  // ACCESSORS
  std::string description() const { return desc; }
  std::string authors() const { return auth; }

  private:
  Protein& _proteinRef; ///< Object that holds all information about currently processed protein chain.
}; // IAlgorithm (abstract) class

} // profo namespace
#endif // ALGORITHM_H
